package com.example.munidingwei

import android.app.*
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import android.util.Log
import androidx.core.app.NotificationCompat
import com.baidu.location.BDAbstractLocationListener
import com.baidu.location.BDLocation
import com.baidu.location.LocationClient
import com.baidu.location.LocationClientOption
import kotlinx.coroutines.*

/**
 * 真实位置上报服务
 * 自动获取真实GPS位置并定期上报到后台服务器
 */
class RealLocationForegroundService : Service() {
    
    companion object {
        private const val TAG = "RealLocationService"
        private const val NOTIFICATION_ID = 2001
        private const val CHANNEL_ID = "real_location_channel"
        private const val CHANNEL_NAME = "真实位置上报服务"
        private const val REPORT_INTERVAL = 30000L // 上报间隔：30秒
        
        private var isRunning = false
        
        /**
         * 启动服务
         */
        fun start(context: Context) {
            val intent = Intent(context, RealLocationForegroundService::class.java)
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
            Log.d(TAG, "🚀 请求启动真实位置服务")
        }
        
        /**
         * 停止服务
         */
        fun stop(context: Context) {
            context.stopService(Intent(context, RealLocationForegroundService::class.java))
            Log.d(TAG, "🛑 请求停止真实位置服务")
        }
        
        fun isServiceRunning(): Boolean = isRunning
    }
    
    private val serviceScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private var reportJob: Job? = null
    
    // WakeLock 保持CPU运行
    private var wakeLock: PowerManager.WakeLock? = null
    
    // BackendClient 用于上报位置
    private var backendClient: BackendClient? = null
    
    // 百度定位客户端
    private var locationClient: LocationClient? = null
    
    // 当前位置信息
    private var currentLatitude: Double = 0.0
    private var currentLongitude: Double = 0.0
    private var currentAccuracy: Float = 0.0f
    private var currentAddress: String = ""
    private var currentLocationName: String = ""
    private var hasValidLocation: Boolean = false
    private var lastLocationUpdateTime: Long = 0 // 上次位置更新时间
    
    // 定位监听器
    private val locationListener = object : BDAbstractLocationListener() {
        override fun onReceiveLocation(location: BDLocation?) {
            if (location == null) {
                Log.w(TAG, "收到空的位置信息")
                return
            }
            
            Log.d(TAG, "========================================")
            Log.d(TAG, "📍 收到百度定位")
            Log.d(TAG, "   定位类型: ${getLocTypeDesc(location.locType)}")
            Log.d(TAG, "   纬度: ${location.latitude}")
            Log.d(TAG, "   经度: ${location.longitude}")
            Log.d(TAG, "   精度: ${location.radius}米")
            Log.d(TAG, "========================================")
            
            // 检查定位是否有效
            if (location.locType == BDLocation.TypeGpsLocation || 
                location.locType == BDLocation.TypeNetWorkLocation ||
                location.locType == BDLocation.TypeOffLineLocation) {
                
                // 更新位置信息
                currentLatitude = location.latitude
                currentLongitude = location.longitude
                currentAccuracy = location.radius
                currentAddress = location.addrStr ?: ""
                currentLocationName = location.locationDescribe ?: ""
                hasValidLocation = true
                lastLocationUpdateTime = System.currentTimeMillis() // 记录更新时间
                
                Log.d(TAG, "✅ 有效定位已保存")
                Log.d(TAG, "   地址: $currentAddress")
                Log.d(TAG, "   位置描述: $currentLocationName")
                
                // 更新通知
                updateNotification()
                
            } else {
                Log.w(TAG, "❌ 定位失败: ${getLocTypeDesc(location.locType)}")
            }
        }
    }
    
    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "========================================")
        Log.d(TAG, "🔧 真实位置服务创建")
        Log.d(TAG, "========================================")
        
        // 初始化BackendClient
        try {
            backendClient = MainApplication.getBackendClient(applicationContext)
            Log.d(TAG, "✅ BackendClient已初始化")
        } catch (e: Exception) {
            Log.e(TAG, "❌ BackendClient初始化失败: ${e.message}")
        }
        
        // 初始化百度定位
        initBaiduLocation()
        
        // 创建通知渠道
        createNotificationChannel()
        
        // 获取 WakeLock
        try {
            val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
            wakeLock = powerManager.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK,
                "RealLocation::ForegroundServiceWakeLock"
            )
            Log.d(TAG, "✅ WakeLock已创建")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 创建WakeLock失败: ${e.message}")
        }
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "========================================")
        Log.d(TAG, "🚀 真实位置服务启动")
        Log.d(TAG, "========================================")
        
        try {
            // 创建通知并启动前台服务
            val notification = createNotification()
            startForeground(NOTIFICATION_ID, notification)
            Log.d(TAG, "✅ 前台服务已启动")
            
            // 获取 WakeLock
            wakeLock?.let {
                if (!it.isHeld) {
                    it.acquire(10 * 60 * 1000L /*10分钟超时*/)
                    Log.d(TAG, "✅ WakeLock已获取")
                }
            }
            
            isRunning = true
            
            // 启动定位
            startLocationUpdates()
            
            // 启动定期上报任务
            startPeriodicReporting()
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 启动前台服务失败: ${e.message}")
            e.printStackTrace()
        }
        
        return START_STICKY
    }
    
    /**
     * 初始化百度定位
     */
    private fun initBaiduLocation() {
        try {
            LocationClient.setAgreePrivacy(true)
            locationClient = LocationClient(applicationContext).apply {
                registerLocationListener(locationListener)
                locOption = LocationClientOption().apply {
                    locationMode = LocationClientOption.LocationMode.Hight_Accuracy // 高精度模式
                    setCoorType("bd09ll") // 百度坐标系
                    setScanSpan(5000) // 每5秒定位一次（提高更新频率，确保位置最新）
                    setIsNeedAddress(true) // 需要地址信息
                    setIsNeedLocationDescribe(true) // 需要位置描述
                    setNeedDeviceDirect(false)
                    setLocationNotify(false)
                    setIgnoreKillProcess(true) // 后台定位
                    setIsNeedLocationPoiList(true) // 需要POI信息
                    SetIgnoreCacheException(false)
                    setIsNeedAltitude(false)
                }
            }
            Log.d(TAG, "✅ 百度定位初始化完成")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 百度定位初始化失败: ${e.message}", e)
        }
    }
    
    /**
     * 启动定位更新
     */
    private fun startLocationUpdates() {
        try {
            locationClient?.start()
            Log.d(TAG, "✅ 定位服务已启动")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 启动定位失败: ${e.message}", e)
        }
    }
    
    /**
     * 停止定位更新
     */
    private fun stopLocationUpdates() {
        try {
            locationClient?.stop()
            Log.d(TAG, "✅ 定位服务已停止")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 停止定位失败: ${e.message}", e)
        }
    }
    
    /**
     * 启动定期上报任务
     */
    private fun startPeriodicReporting() {
        reportJob?.cancel()
        
        Log.d(TAG, "========================================")
        Log.d(TAG, "⏰ 启动定期上报任务")
        Log.d(TAG, "   上报间隔: ${REPORT_INTERVAL / 1000}秒")
        Log.d(TAG, "========================================")
        
        reportJob = serviceScope.launch {
            var reportCount = 0
            
            while (isActive) {
                try {
                    delay(REPORT_INTERVAL)
                    
                    if (hasValidLocation) {
                        reportCount++
                        Log.d(TAG, "")
                        Log.d(TAG, "========================================")
                        Log.d(TAG, "📡 第 $reportCount 次上报位置")
                        Log.d(TAG, "========================================")
                        
                        reportLocationToBackend()
                    } else {
                        Log.w(TAG, "⚠️ 还没有有效的定位数据，跳过上报")
                    }
                    
                } catch (e: CancellationException) {
                    Log.d(TAG, "定期上报任务被取消")
                    throw e
                } catch (e: Exception) {
                    Log.e(TAG, "❌ 定期上报失败: ${e.message}", e)
                }
            }
        }
    }
    
    /**
     * 上报位置到后台
     * 确保获取最新位置后再上报
     */
    private fun reportLocationToBackend() {
        try {
            if (backendClient == null) {
                Log.e(TAG, "❌ BackendClient未初始化，跳过上报")
                return
            }
            
            if (!hasValidLocation) {
                Log.w(TAG, "⚠️ 没有有效位置，跳过上报")
                return
            }
            
            // 🔥 在上报前，如果位置数据较旧（超过5秒），先请求一次最新定位
            val currentTime = System.currentTimeMillis()
            val timeSinceLastUpdate = currentTime - lastLocationUpdateTime
            
            if (timeSinceLastUpdate > 5000) { // 如果位置数据超过5秒未更新
                Log.d(TAG, "📍 位置数据较旧（${timeSinceLastUpdate / 1000}秒前），先请求最新定位")
                
                // 请求一次定位更新
                locationClient?.requestLocation()
                
                // 等待定位结果（最多等待2秒）
                var waitCount = 0
                while (waitCount < 20 && (System.currentTimeMillis() - lastLocationUpdateTime) < 2000) {
                    Thread.sleep(100)
                    waitCount++
                }
                
                if (System.currentTimeMillis() - lastLocationUpdateTime < 3000) {
                    Log.d(TAG, "✅ 已获取最新位置")
                } else {
                    Log.w(TAG, "⚠️ 等待定位超时，使用缓存位置")
                }
            }
            
            // 构造位置数据（使用最新获取的位置）
            val locationData = LocationData(
                latitude = currentLatitude,
                longitude = currentLongitude,
                accuracy = currentAccuracy,
                timestamp = System.currentTimeMillis(),
                address = currentAddress,
                isSimulated = false, // 真实位置
                locationName = currentLocationName
            )
            
            Log.d(TAG, "📍 准备上报位置:")
            Log.d(TAG, "   纬度: $currentLatitude")
            Log.d(TAG, "   经度: $currentLongitude")
            Log.d(TAG, "   精度: $currentAccuracy 米")
            Log.d(TAG, "   地址: $currentAddress")
            Log.d(TAG, "   描述: $currentLocationName")
            Log.d(TAG, "   时间戳: ${locationData.timestamp}")
            Log.d(TAG, "   位置更新时间: ${(System.currentTimeMillis() - lastLocationUpdateTime) / 1000}秒前")
            
            // 上报到后台
            backendClient?.reportLocation(locationData)
            
            Log.d(TAG, "✅ 位置数据已发送到BackendClient")
            Log.d(TAG, "========================================")
            
        } catch (e: Exception) {
            Log.e(TAG, "========================================")
            Log.e(TAG, "❌ 上报位置失败!")
            Log.e(TAG, "   错误: ${e.message}")
            e.printStackTrace()
            Log.e(TAG, "========================================")
        }
    }
    
    /**
     * 创建通知渠道
     */
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                CHANNEL_NAME,
                NotificationManager.IMPORTANCE_MIN  // 最低优先级，通知会被折叠
            ).apply {
                description = "后台位置上报服务"
                setShowBadge(false)  // 不显示角标
                setSound(null, null)  // 无声音
                enableVibration(false)  // 不震动
                enableLights(false)  // 不闪灯
            }
            
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
    
    /**
     * 创建通知（最小化显示）
     */
    private fun createNotification(): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("位置服务")
            .setContentText("后台运行中")
            .setSmallIcon(android.R.drawable.ic_menu_mylocation)
            .setPriority(NotificationCompat.PRIORITY_MIN)  // 最低优先级
            .setOngoing(true)  // 持续运行
            .setShowWhen(false)  // 不显示时间
            .setSound(null)  // 无声音
            .setVibrate(null)  // 不震动
            .build()
    }
    
    /**
     * 更新通知（已禁用，保持简洁）
     */
    private fun updateNotification() {
        // 不再更新通知内容，保持最小化显示
        // 如果需要更新，取消注释下面的代码
        /*
        try {
            val notification = createNotification()
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.notify(NOTIFICATION_ID, notification)
        } catch (e: Exception) {
            Log.e(TAG, "更新通知失败: ${e.message}")
        }
        */
    }
    
    /**
     * 任务被移除时（用户划掉任务）
     */
    override fun onTaskRemoved(rootIntent: Intent?) {
        super.onTaskRemoved(rootIntent)
        Log.d(TAG, "⚠️ 任务被移除，准备重启服务")
        
        // 重启服务
        val restartIntent = Intent(applicationContext, RealLocationForegroundService::class.java)
        val pendingIntent = PendingIntent.getService(
            applicationContext,
            1,
            restartIntent,
            PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
        )
        
        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val time = System.currentTimeMillis() + 1000
        alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent)
    }
    
    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "========================================")
        Log.d(TAG, "🛑 真实位置服务销毁")
        Log.d(TAG, "========================================")
        
        isRunning = false
        
        // 停止定期上报
        reportJob?.cancel()
        
        // 停止定位
        stopLocationUpdates()
        
        // 释放 WakeLock
        wakeLock?.let {
            if (it.isHeld) {
                it.release()
                Log.d(TAG, "✅ WakeLock已释放")
            }
        }
        
        // 注销定位监听
        locationClient?.unRegisterLocationListener(locationListener)
        
        Log.d(TAG, "服务已完全停止")
    }
    
    override fun onBind(intent: Intent?): IBinder? = null
    
    /**
     * 获取定位类型描述
     */
    private fun getLocTypeDesc(locType: Int): String {
        return when (locType) {
            BDLocation.TypeGpsLocation -> "GPS定位"
            BDLocation.TypeNetWorkLocation -> "网络定位"
            BDLocation.TypeOffLineLocation -> "离线定位"
            BDLocation.TypeServerError -> "服务器错误"
            BDLocation.TypeNetWorkException -> "网络异常"
            BDLocation.TypeCriteriaException -> "条件异常"
            else -> "未知类型($locType)"
        }
    }
}

